#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QString>
#include "mybutton.h"
#include <QTcpSocket>
#include <QTimer>
#include <QLabel>
#include "playvideo.h"
#include <QButtonGroup>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QJsonObject>
#include <QJsonArray>
#include <QSlider>
#include <QComboBox>
#include <QThread>

#define DPI_LOW 1
#define DPI_MEDIUM 5
#define DPI_HIGH 10

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void EnableButton(); //使能所有按钮
    void DisableButton(); //禁用所有按钮
    void EnablePrivileged(); //使能特权相关按钮
    void DisablePrivileged(); //禁用特权相关按钮
public slots:
    //模块一的连接机械臂对应槽函数
    void ConnectRobot();    //连接机械臂，当按下connect按钮时触发
    void ConnectError();    //提示连接失败，当连接超时时自动触发
    void ConnectOk();       //提示连接成功，当连接机械臂成功时自动触发
    void ReadMsg();         //接收机械臂返回的坐标点信息，当机械臂移动完成后发送
    //模块二的工作模式选择对应槽函数
    void ModeChange(const QString &text);   //根据工作模式不同改变按钮的权限， 当Combox的选择项发生改变时触发
    //模块三开合夹爪对应的槽函数
    void GrabClawSlot();    //发送消息要求机械臂打开夹爪，当GrabClaw按钮按下时触发
    void ReleaseClawSlot(); //发送消息要求机械臂关闭夹爪，当Release按钮按下时触发
    //模块四自动工作对应的槽函数
    void ModeoneStart();    //OpenCV定位，自动夹取模式，当ModeOne按钮被按下时触发
    void ModetwoStart();    //机械臂自动执行提前设置好的夹取任务，当ModeTwo按钮被按下时触发
    //模块五获取摄像头图像对应的槽函数
    void ShowVideo(QImage image);   //接收OpenCV图像后加载到主界面中，当启动OpenCV线程，同时照相机识别到图像时触发
    void RecvPotint(QPoint point);  //接收定位物品的中心点后发送定位坐标给机械臂，当成功定位物品时触发
    //单动模式下，按钮被点击时对应槽函数
    void XUpTillSlot();     //发送消息要求机械臂朝x轴正方向移动DPI距离，当XUp按钮被点击时触发
    void XDownTillSlot();   //发送消息要求机械臂朝x轴负方向移动DPI距离，当XDown按钮被点击时触发
    void YUpTillSlot();     //发送消息要求机械臂朝y轴正方向移动DPI距离，当YUp按钮被点击时触发
    void YDownTillSlot();   //发送消息要求机械臂朝y轴负方向移动DPI距离，当YDown按钮被点击时触发
    void ZUpTillSlot();     //发送消息要求机械臂朝z轴正方向移动DPI距离，当ZUp按钮被点击时触发
    void ZDownTillSlot();   //发送消息要求机械臂朝z轴负方向移动DPI距离，当ZDown按钮被点击时触发
    //单动模式下，按钮被按压时对应的槽函数
    void XUpEinmalSlot();   //发送消息要求机械臂朝x轴正方向一直移动，每次移动DPI距离，当XUp按钮被长按时触发
    void XDownEinmalSlot(); //发送消息要求机械臂朝x轴负方向一直移动，每次移动DPI距离，当XDown按钮被长按时触发
    void YUpEinmalSlot();   //发送消息要求机械臂朝y轴正方向一直移动，每次移动DPI距离，当YUp按钮被长按时触发
    void YDownEinmalSlot(); //发送消息要求机械臂朝y轴负方向一直移动，每次移动DPI距离，当YDown按钮被长按时触发
    void ZUpEinmalSlot();   //发送消息要求机械臂朝z轴正方向一直移动，每次移动DPI距离，当ZUp按钮被长按时触发
    void ZDownEinmalSlot(); //发送消息要求机械臂朝z轴负方向一直移动，每次移动DPI距离，当ZDown按钮被长按时触发
    //单动模式下，按钮被松开时对应的槽函数
    void ButtonReleasedSlot();  //发送消息要求机械臂停止运动，当XYZ的Up/Down按钮长按松开时触发
    //xyz发送的槽函数
    void ButtonXYZSlot();   //发送XYZ的LineEdit输入的坐标点给机械臂，当RobotMotion按钮被按下时触发
private:
    QTcpSocket *MyTcp;
    QTimer *TimeoutCheck;
    //模块一---输入ip和port后，点击连接按钮与服务器建立连接
    QLineEdit *IpEdit;//ip的输入框
    QLineEdit *PortEdit;//ip的输入框
    MyButton *Connect;//连接按钮
    //模块二---模式选择，不同模式下权限不同，也就是能执行的操作不同
    QLabel *SelextMode;//一个提示框，提示你选择模式
    QComboBox *Mode;//下拉框，里面提供两种模式供你选择，特权模式和用户模式
    //模块三---爪子的开合控制
    MyButton *Grab;//该按钮是一个爪子闭合按钮
    MyButton *Release;//该按钮是一个爪子松开按钮
    //模块四---经过调试后设置的几种工作模式
    MyButton *ModeOne;  //将摄像头采集到的物品的x，y，z数据发送给机械臂实现抓取功能
    MyButton *ModeTwo;  //让机械臂自动执行提前调试好坐标点的抓取任务
    MyButton *ModeThree;
    MyButton *ModeFour;
    MyButton *ModeFive;
    MyButton *ModeSix;
    bool ModeEnable;
    //模块五---显示摄像头采集到的画面
    QLabel *VideoLabel;//用于将摄像头画面显示在上面的控件
    PlayVideo *VideoThread;//自定义的Video线程类
    //模块六---目标空间位置，实时显示机械臂的空间位置以及能够手动输入空间位置使机械臂移动
    QLineEdit *RobotX;//X的空间位置输入显示框
    QLineEdit *RobotY;//Y的空间位置输入显示框
    QLineEdit *RobotZ;//Z的空间位置输入显示框
    MyButton *RobotMotion;//点击该按钮发送想要移动的位置给机械臂
    //模块七---点动控制的六个按钮单独的控制x、y、z方向的正向移动和反向移动。滑块用来决定移动的精度
    MyButton *XUp;//X的正向移动
    MyButton *XDown;//X的反向移动
    MyButton *YUp;//Y的正向移动
    MyButton *YDown;//Y的反向移动
    MyButton *ZUp;//Z的正向移动
    MyButton *ZDown;//Z的反向移动
    QSlider *Slider;//该滑块有三个档，分别是1、10、100
    QLabel *SliderLab;//用于显示当前滑块是哪一个档
    QJsonObject TransmitJson;//JSON对象，用于创建和添加键值对和数组
    QJsonArray Position;//表示一个JSON数组
    //接收数据的线程
    QThread ReadMsgThread;
};
#endif // WIDGET_H
